package top.callback.inf.beautyleaf.segment.model;

import lombok.Data;

import java.util.concurrent.atomic.AtomicLong;

/**
 * 号码段是持有一段连续 ID 的容器，号码段算法每次会申请指定步长数量的 ID 组成一个号码段，号码段维护这些 ID 并
 * 将这些 ID 发出去。
 *
 * @author Pengyu Gan
 * CreateDate 2021/3/23
 */
@Data
public class Segment {

    /**
     * 号码段当前已发的最大 ID
     */
    private AtomicLong value = new AtomicLong(0);

    /**
     * 号码段最大可发的 ID 号
     */
    private volatile long max;

    /**
     * 号码段的步长，即号码段可持有的最大 ID 数量
     */
    private volatile int step;

    /**
     * 号码段所在的缓冲区，详见 {@link SegmentBuffer}
     */
    private SegmentBuffer buffer;

    public Segment(SegmentBuffer buffer) {
        this.buffer = buffer;
    }

    /**
     * 获取号码段的剩余 ID 数量（即还有多少 ID 没有发出去）
     * @return ID 剩余数
     */
    public long getIdle() {
        return this.getMax() - getValue().get();
    }

    /**
     * 注意这里不要输出 SegmentBuffer，否则会死循环导致栈溢出
     * @return toString
     */
    @Override
    public String toString() {
        return "Segment{" +
                "value=" + value +
                ", max=" + max +
                ", step=" + step +
                '}';
    }
}
